package com.pisolution.scheduler.datasource.instance;

import com.pisolution.scheduler.datasource.command.CommandType;
import com.pisolution.scheduler.datasource.workflow.Workflow;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;

/**
 * 工作流实例数据实体.
 *
 * @author sora
 * @version 0.1.0
 */
@TableName(value = "workflow_instance")
public class WorkflowInstance {
    // -------------------------------------------------------------------------------------------------
    //  数据单元 (基础信息)
    // -------------------------------------------------------------------------------------------------

    /** 工作流实例标识. */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /** 工作流实例名称. */
    @TableField(value = "name")
    private String name;

    /** 工作流实例优先级. */
    @TableField(value = "priority")
    private Priority priority;

    /** 工作流实例完整内容 json格式. */
    @TableField(value = "content")
    private String content;

    // -------------------------------------------------------------------------------------------------
    //  数据单元 (关联信息)
    // -------------------------------------------------------------------------------------------------

    /** 所属工作流标识. */
    @TableField(value = "workflow_id")
    private int workflowId;

    /** 所属工作流. */
    @TableField(value = "workflow", exist = false)
    private Workflow workflow;

    /** 执行工作流实例的用户标识. */
    @TableField(value = "user_id")
    private Integer userId;

    /** 失败策略. */
    @TableField(value = "strategy")
    private FailureStrategy strategy;

    /** 通知策略. */
    @TableField(value = "warning_type")
    private WarningType warningType;

    /** 通知组标识. */
    @TableField(value = "warning_group_id")
    private Integer warningGroupId;

    /** 指令类型. */
    @TableField(value = "command_type")
    private CommandType commandType;

    /** 指令参数. */
    @TableField(value = "command_params")
    private String commandParams;

    /** 指令开始处理时间. */
    @TableField(value = "command_start_time")
    private Date commandStartTime;

    /** 指令调度时间. */
    @TableField(value = "schedule_time")
    private Date scheduleTime;

    // -------------------------------------------------------------------------------------------------
    //  数据单元 (执行环境)
    // -------------------------------------------------------------------------------------------------

    /** 负责拆解工作流并管理运行期实例的管理节点主机地址. */
    @TableField(value = "host")
    private String host;

    /** 运行该工作流实例的工作节点所在分组. */
    @TableField(value = "worker_group")
    private String workerGroup;

    /** 最大重试次数. */
    @TableField(value = "max_retry_count")
    private int maxRetryCount;

    // -------------------------------------------------------------------------------------------------
    //  数据单元 (运行信息)
    // -------------------------------------------------------------------------------------------------

    /** 工作流实例运行状态. */
    @TableField(value = "state")
    private ExecutionState state;

    /** 开始运行时间. */
    @TableField(value = "start_time")
    private Date startTime;

    /** 结束运行时间. */
    @TableField(value = "end_time")
    private Date endTime;

    /** 运行时间. */
    @TableField(value = "duration", exist = false)
    private Long duration;

    /** 运行次数. */
    @TableField(value = "run_times")
    private int runTimes;

    /** 是否正在进行失效转移. */
    @TableField(value = "is_recovery")
    private Flag isRecovery;

    /** 历史运行命令. */
    @TableField(value = "history_command")
    private String historyCmd;

    /** 工作流实例运行超时时间. */
    @TableField(value = "timeout")
    private int timeout;

    // -------------------------------------------------------------------------------------------------
    //  初始化
    // -------------------------------------------------------------------------------------------------

    public WorkflowInstance(final Workflow workflow) {
        this.workflow = workflow;
        this.name = workflow.getName() + '-' + workflow.getVersion() + '-' + System.currentTimeMillis();
    }

    // -------------------------------------------------------------------------------------------------
    //  属性访问
    // -------------------------------------------------------------------------------------------------

    public Integer getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public Priority getPriority() {
        return this.priority;
    }

    public void setPriority(Priority priority) {
        this.priority = priority;
    }

    public String getContent() {
        return this.content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getWorkflowId() {
        return this.workflowId;
    }

    public void setWorkflowId(int workflowId) {
        this.workflowId = workflowId;
    }

    public Workflow getWorkflow() {
        return this.workflow;
    }

    public void setWorkflow(Workflow workflow) {
        this.workflow = workflow;
    }

    public Integer getUserId() {
        return this.userId;
    }

    public FailureStrategy getStrategy() {
        return this.strategy;
    }

    public void setStrategy(FailureStrategy strategy) {
        this.strategy = strategy;
    }

    public WarningType getWarningType() {
        return this.warningType;
    }

    public void setWarningType(WarningType warningType) {
        this.warningType = warningType;
    }

    public Integer getWarningGroupId() {
        return this.warningGroupId;
    }

    public void setWarningGroupId(Integer warningGroupId) {
        this.warningGroupId = warningGroupId;
    }

    public void setCommandType(CommandType commandType) {
        this.commandType = commandType;
    }

    public void setCommandParams(String commandParams) {
        this.commandParams = commandParams;
    }

    public void setCommandStartTime(Date commandStartTime) {
        this.commandStartTime = commandStartTime;
    }

    public Date getScheduleTime() {
        return this.scheduleTime;
    }

    public void setScheduleTime(Date scheduleTime) {
        this.scheduleTime = scheduleTime;
    }

    public String getHost() {
        return this.host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getWorkerGroup() {
        return this.workerGroup;
    }

    public void setWorkerGroup(String workerGroup) {
        this.workerGroup = workerGroup;
    }

    public void setMaxRetryCount(int maxRetryCount) {
        this.maxRetryCount = maxRetryCount;
    }

    public ExecutionState getState() {
        return this.state;
    }

    public void setState(ExecutionState state) {
        this.state = state;
    }

    public Date getStartTime() {
        return this.startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public int getRunTimes() {
        return this.runTimes;
    }

    public void setRunTimes(int runTimes) {
        this.runTimes = runTimes;
    }

    public void setIsRecovery(Flag isRecovery) {
        this.isRecovery = isRecovery;
    }

    public int getTimeout() {
        return this.timeout;
    }

    // -------------------------------------------------------------------------------------------------
    //  辅助方法
    // -------------------------------------------------------------------------------------------------

    /**
     * 将给定指令类型追加到历史指令集中.
     *
     * @param type 待追加到历史指令集中的指令.
     */
    public void addHistoryCmd(CommandType type) {
        if (StringUtils.isBlank(historyCmd)) {
            this.historyCmd = type.toString();

            return;
        }

        this.historyCmd = String.format("%s,%s", this.historyCmd, type.toString());
    }
}
